package com.example.shotscreen;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Alex-Zhang on 2017/11/6.
 */

public class CreateBitmap extends View {

    private TextPaint mPaint;
    private Path path;
    private float radius;
    private String stampDate;

    private String stampContent ="dfasdfdsfasd";
    private float dateStartAngle;
    private float angleStartContent;
    private Paint paint;
    private RectF rectF;
    private float angleContent;
    private int tintColor = Color.parseColor("#FF766C");
    // private int tintColor = Color.BLUE;
    private float scaleRatio;
    private float angleDate;

    public int DEFAULT_WIDTH;
    public int DEFAULT_HEIGHT;
    private Bitmap rawBitmap;

    private Bitmap bitmap;

    public CreateBitmap(Context context) {
        this(context, null);
    }

    public CreateBitmap(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CreateBitmap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void setStampContent(String stampContent) {
        this.stampContent = stampContent;
        invalidate();
    }

    public void setTintColor(int tintColor) {
        this.tintColor = tintColor;
        invalidate();
    }

    private void init(Context context) {
        DEFAULT_WIDTH = convertDpToPx(context, 50);
        DEFAULT_HEIGHT = convertDpToPx(context, 50);

        mPaint = new TextPaint();
        mPaint.setAntiAlias(true);

        mPaint.setColor(tintColor);
        mPaint.setTextSize(46);

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.BLACK);

        rawBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.postmark);

        scaleRatio = (float) rawBitmap.getWidth() / (float) rawBitmap.getHeight();

        path = new Path();
        stampDate = formatDate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST) {
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_WIDTH, MeasureSpec.EXACTLY);
        }
        if (heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_HEIGHT, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        PointF pointF = calculateBitmapDimension(getMeasuredWidth(), getMeasuredHeight());
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(rawBitmap, (int) pointF.x, (int) pointF.y, false);

        radius = convertDpToPx(getContext(), 67 * (pointF.x / (float) rawBitmap.getWidth()));
        PointF center = new PointF(scaledBitmap.getHeight() / 2, scaledBitmap.getHeight() / 2);

        float contextWidth = mPaint.measureText(stampContent);
        float dateWidth = mPaint.measureText(stampDate);
        angleContent = calculateAngle(contextWidth);
        angleDate = calculateAngle(dateWidth);
        dateStartAngle = 270 - (angleDate / 2);
        angleStartContent = 90 - (angleContent / 2);
        rectF = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
        bitmap = tintBitmap(scaledBitmap, tintColor);

    }

    private PointF calculateBitmapDimension(int w, int h) {
        PointF pointF = new PointF();

        float rawRatio = (float) w / (float) h;

        if (rawRatio >= 1) {
            if (w <= rawBitmap.getWidth()) {
                pointF.y = h;
                pointF.x = (float) w * scaleRatio;
            } else {
                pointF.x = rawBitmap.getWidth();
                pointF.y = rawBitmap.getHeight();
            }
        } else {
            if (h <= rawBitmap.getHeight()) {
                pointF.x = w;
                pointF.y = (float) w * scaleRatio;
            } else {
                pointF.x = rawBitmap.getWidth();
                pointF.y = rawBitmap.getHeight();
            }
        }
        return pointF;
    }

    @Override
    protected void onDraw(Canvas canvas) {
            canvas.restore();
            path.rewind();
            path.addArc(rectF, dateStartAngle, angleDate);
            canvas.drawBitmap(bitmap, 0, 0, paint);
            canvas.drawTextOnPath(stampDate, path, 0, 0, mPaint);
            canvas.save();
            path.rewind();
            path.addArc(rectF, angleStartContent, angleContent);
            canvas.drawTextOnPath(stampContent, path, 0, 0, mPaint);
            canvas.save();

    }

    private float calculateAngle(float arc) {
        return (float) ((180.f * arc) / (Math.PI * radius));
    }


    public static int convertDpToPx(Context context, float dp) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    public Bitmap tintBitmap(Bitmap inBitmap, int tintColor) {
        if (inBitmap == null) {
            return null;
        }
        Bitmap outBitmap = Bitmap.createBitmap(inBitmap.getWidth(), inBitmap.getHeight(), inBitmap.getConfig());
        Canvas canvas = new Canvas(outBitmap);
        Paint paint = new Paint();
        paint.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(inBitmap, 0, 0, paint);
        return outBitmap;
    }

    private String formatDate() {
        SimpleDateFormat format = new SimpleDateFormat("MMM d , yyyy", Locale.US);
        return format.format(new Date());
    }
}
